﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ascend.Runtime.Core;
using Zove.Runtime.Core;
using Zove.Runtime.Queries;
using EmbeddedSharp.Core.TextConentProviders;

namespace Zove.Runtime.Test {
    /// <summary>
    /// Summary description for AscendLanguageTests
    /// </summary>
    [TestClass]
    public class AscendLanguageTests {
        public AscendLanguageTests() {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext {
            get {
                return testContextInstance;
            }
            set {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestVapor() {
            AscendLanguageNature languageNature = new AscendLanguageNature();

            QueryManager qm = new QueryManager(languageNature);
            Query query = qm.CreateQuery("select * from Vapor where x1=0.6, T=75");

            Dictionary<string, QueryResult> results = query.Run();
            foreach(QueryResult result in results.Values)
            {
                Console.WriteLine(result.ToString());
            }
        }

        [TestMethod]
        public void TestThinTank()
        {
            const string source =
                @"
MODEL thin_walled_tank;

    D,
    H,
    wall_thickness,
    metal_density,

    end_area,
    side_area,
    wall_vol,
    metal_mass      IS_A factor;

    D              = 20.0;
    H              = 50.0;

    wall_thickness = 0.15;
    metal_density  = 7.85;

    end_area = 3.1416*D^2/4;
    side_area = 3.1416*D*H;

    (side_area+2*end_area)*wall_thickness = wall_vol;
    metal_mass = metal_density*wall_vol;

END thin_walled_tank;
";

            AscendLanguageNature languageNature = new AscendLanguageNature();
            ZoveObject zoveObject = new ZoveObject(string.Empty, new StringContentProvider(source), languageNature);

            RuntimeFactorCollection factors = zoveObject.Where("metal_mass = 5000").Select("*");

            foreach(RuntimeFactor factor in factors)
            {
                Console.WriteLine(factor);
            }
        }

        [TestMethod]
        public void TestDerive()
        {
            const string baseClass = @"
MODEL tank;
    V IS_A volume;
    rho IS_A density;

    mdot IS_A mass_rate;
    Vdot IS_A volume_rate;
    Vdot = mdot * rho;

END tank;

MODEL pipe;
    mdot IS_A mass_rate;

    rho IS_A density;
END pipe;

MODEL tank_and_pipe;

    T IS_A tank;
    P IS_A pipe;
    T.rho, P.rho ARE_THE_SAME;

    P.mdot, T.mdot ARE_THE_SAME;
END tank_and_pipe;
";

            const string source = @"
MODEL vessel REFINES tank;
    p IS_A pressure;
    R IS_A gas_constant;
    n IS_A factor;

    T IS_A temperature;
    p*V = n * R * T;

    T_amb IS_A temperature;
    T = T_amb + 20 {K};
END vessel;
";

            AscendLanguageNature languageNature = new AscendLanguageNature();
        }

        [TestMethod]
        public void TestParameterisedModel()
        {
            
        }

        [TestMethod]
        public void TestAlias()
        {
            
        }

        [TestMethod]
        public void TestAreTheSame()
        {
            
        }
    }
}
